import { any } from "../../core/logic";
import { guid } from "../../core/utils";
import { Sampler } from "./Sampler";
/**
 * 动画通道类，一个通道包含三部分信息。
 * 1. target：动画的作用对象。
 * 2. path：动画作用对象的具体属性。
 * 3. sampler：采样数据，{@link w.animation.Sampler}
 * @class
 * @memberof w.animation
 */
class Channel {
    /**
     * @constructor
     * @param {Object} target 通道作用的目标对象。
     * @param {String} path 通道作用的目标对象中的属性。
     */
    constructor(target, path,id) {
        this.id = any(id,guid());
        this.target = target;
        this.path = path;
        this.samplers = [];
    }
    /**
     * 添加采样器。
     * @method
     * @param {Sampler} sampler 
     */
    add (sampler) {
        let index = this.samplers.indexOf(sampler);
        if (index >= 0) {
            this.samplers.splice(index, 1);
        }
        this.samplers.push(sampler);

    }
    /**
     * 移除采样器。
     * @method
     * @param {String} sampler Sampler.id or Sampler
     */
    remove (sampler) {
        let id = "";
        if (sampler instanceof Sampler) {
            id = sampler.id;
        } else {
            id = sampler;
        }
        for (let i = this.samplers.length - 1; i >= 0; i--) {
            if (this.samplers[i].id === id) {
                this.samplers.splice(i, 1);
                break;
            }
        }
    }
    play (time) {
        let frameInfos=[];
        for (let i = 0; i < this.samplers.length; i++) {
            const sampler = this.samplers[i];
            let frameInfo=sampler.findKeyFrame(time);
            frameInfo.target=this.target;
            frameInfo.path=this.path;
            frameInfos.push(frameInfo);
            let result = frameInfo.result;
            
            if (Array.isArray(this.target)) {
                for (let index = 0; index < this.target.length; index++) {
                    const element = this.target[index];
                    if (this.path === "weights") {//变形动画特殊处理
                        const geometry = element
                        const morphTargets = geometry.morphTargets
                        const geometryObject = {};
                        for (const targetAttribute in morphTargets[0]) {
                            if (targetAttribute !== 'POSITION') {
                                continue;
                            }
                            geometryObject[targetAttribute] = geometry[targetAttribute.toLowerCase()+`1`].slice();
                       
                            for (let i = 0; i < result.length; i++) {
                                if (result[i] === 0) {
                                    continue;
                                }
                                const offset = 0;
                                for (let l = 0; l < geometryObject[targetAttribute].length; l++) {
                                    geometryObject[targetAttribute][l] += result[i] * morphTargets[i][targetAttribute][l - offset];
                                }
    
                            }
                            geometry[targetAttribute.toLowerCase()]= geometryObject[targetAttribute]
                        }
                    } else {
                        element[this.path] = result;
                    }

                }
            } else {
                if (this.path === "weights") {//变形动画特殊处理
                    const geometry = this.target
                    geometry.morphWeight=result
                } else {
                    this.target[this.path] = result;
                }
            }
        }
        return frameInfos;
    }
    timeLine () {
        let min = Number.MAX_VALUE, max = Number.MIN_VALUE;
        for (let i = 0; i < this.samplers.length; i++) {
            const sampler = this.samplers[i];
            let timeLine = sampler.timeLine();
            min = Math.min(min, timeLine[0]);
            max = Math.max(max, timeLine[1]);
        }
        return [min, max];
    }
}
export { Channel }